from django.shortcuts import render
from django.http import HttpResponse, JsonResponse

from celery_tasks.sms.tasks import send_sms_code
from dj31.utils.captcha.captcha import captcha
from django_redis import get_redis_connection
from django.views import View


import logging

from dj31.utils.yuntongxun.sms import CCP

logger = logging.getLogger('django')

from users.models import Users
from dj31.utils.response_code import res_json, Code, error_map
import random       # 导入随机数模块，用于生成短信验证码

# 图形验证
def Iamge_code(request, img_id):
    text, image = captcha.generate_captcha()           # text 验证码文本，image 验证码图片

    # 保存    键      过期时间
    redis_coon = get_redis_connection('verify_code')   # 连接redis库

    img_key = "img_{}".format(img_id).encode('utf8')   # 获取图片验证码的键

    redis_coon.setex(img_key,300,text)                 # 设置过期时间

    logger.info("img code: {}".format(text))           # 打印验证码

    # 把图形验证码缓存到session中
    # request.session['image_code'] = text
    # request.session.set_expiry(60)      # 设置过期时间
    # print(request.session.keys())       # 获取session键
    # print(request.session.values())     # 获取session值
    # print(request.session.get('image_code'))

    return HttpResponse(content=image,content_type='image/jpg')


# 用户名验证
class CheckUsernameView(View):
    """
    验证用户名
    route：username/(?P<username>\w{5,20})/
    """
    def get(self,request,username):
        """
        统计数量    如果用户名重复  他的数量变成1
        """
        count = Users.objects.filter(username=username).count()
        data = {
            'username':username,
            'count':count
        }

        # json格式
        # return JsonResponse({'data':data})
        return res_json(data=data)

# 手机号验证
class CheckMobileView(View):
    """
    route: mobiles/(?P<mobile>1[3-9]\d{9}/)
    """
    def get(self,request,mobile):

        data = {
            'mobile': mobile,
            'count': Users.objects.filter(mobile=mobile).count()
        }

        # return JsonResponse({'data':dt})

        return res_json(data=data)

# 注册验证
import json
class SmsCodeView(View):
    def post(self,request):
        """
        参数：手机号  uuid  图形验证码
            'mobile': $mobile.val(),     //手机号
            'text': text,                //图形验证码文本
            'image_code_id': image_code_uuid,   //uuid
        :param request:
        :return:
        """
        # 接收参数
        json_str = request.body

        if not json_str:
            return res_json(errno=Code.PARAMERR, errmsg='参数错误')         #4103

        dict_data = json.loads(json_str)        # json字符串转成字典

        image_code_client = dict_data.get('text')
        uuid = dict_data.get('image_code_id')
        mobile = dict_data.get('mobile')

        # 参数验证
        if not all([image_code_client,uuid,mobile]):
            return res_json(errno=Code.PARAMERR, errmsg='参数错误')

        # 连接数据库
        redis_coon = get_redis_connection('verify_code')

        # 60秒有发送记录
        send_flag = redis_coon.get('sms_flag_{}'.format(mobile))
        if send_flag:
            return res_json(errno=Code.DATAEXIST, errmsg='短信验证码发送频繁')

        image_code_server = redis_coon.get('img_{}'.format(uuid))   # 服务器的uuid

        if image_code_server is None:           # 如果服务器uuid不存在，则报错
            return res_json(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])

        # 删除数据库的验证码 防止重复测试
        try:
            redis_coon.delete('img_{}'.format(uuid))
        except Exception as e:
            logger.error(e)

        # 比对图形验证码
        image_code_server = image_code_server.decode()
        if image_code_client.lower() != image_code_server.lower():  # 强转小写
            return res_json(errno=Code.PARAMERR, errmsg='图形验证码输入有误')

        # 生成短信验证码(6位数)   前面用0补全
        sms_code = '%06d' % random.randint(0,999999)

        # 存到数据库，下一次使用
        redis_coon.setex('sms_{}'.format(mobile),300,sms_code)      # 5分钟有效期300秒

        # 标记手机号在60秒内有发送过短信
        redis_coon.setex('sms_flag_{}'.format(mobile),60,1)

        # 日志记录
        logger.info('短信验证码是:{}'.format(sms_code))
        logging.info('发送短信成功[mobile:{} sms_code:{}]'.format(mobile,sms_code))

        # 调用接口发短信
        ccp = CCP()
        ccp.send_template_sms(mobile, [sms_code,5], 1)

        # send_sms_code.delay(mobile,sms_code)

        return res_json(errmsg='短信验证码发送成功')


send_sms = SmsCodeView.as_view()




